package com.xuecheng.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.commons.constants.OrdersConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.RecordDto;
import com.xuecheng.commons.model.vo.CoursePubIndexVo;
import com.xuecheng.commons.model.vo.OrdersVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.learning.api.LearningClient;
import com.xuecheng.order.config.PayTemplate;
import com.xuecheng.order.domain.Orders;
import com.xuecheng.order.domain.Payment;
import com.xuecheng.order.mapper.OrdersMapper;
import com.xuecheng.order.service.OrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.order.service.PaymentService;
import com.xuecheng.search.api.SearchClient;
import com.xuecheng.web.exception.BusinessException;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author HuangYuwu
 * @since 2022-09-16
 */
@Service
@Slf4j
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired
    private SearchClient searchClient;

    @Autowired
    private PayTemplate payTemplate;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private LearningClient learningClient;

    /**
     * 创建订单
     *
     * @param coursePubId
     * @return
     */
    @Override
    public ResponseResult createOrders(Long coursePubId) {
        Long userId = AuthInfoHolder.getUserId();
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getUserId, userId);
        queryWrapper.eq(Orders::getCoursePubId, coursePubId);
        queryWrapper.eq(Orders::getStatus, OrdersConstants.ORDER_PAID_STATUS);
        long count = this.count(queryWrapper);
        if (count > 0) {
            //已购买
            throw new BusinessException(ErrorCode.ORDERERROR);
        }
        LambdaQueryWrapper<Orders> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Orders::getUserId, userId);
        queryWrapper1.eq(Orders::getCoursePubId, coursePubId);
        queryWrapper1.eq(Orders::getStatus, OrdersConstants.ORDER_INIT_STATUS);
        Orders orders = this.getOne(queryWrapper1);
        if (ObjectUtil.isNotEmpty(orders)) {
            //已下单
            return ResponseResult.okResult(orders.getOrderNo());
        }
        Orders order = new Orders();
        order.setOrderNo(IdUtil.simpleUUID());
        order.setCoursePubId(coursePubId);
        ResponseResult<CoursePubIndexVo> result = searchClient.findById(String.valueOf(coursePubId));
        if (result.getCode() != 0) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        CoursePubIndexVo indexVo = result.getData();
        order.setCreateDate(DateUtil.date());
        order.setCoursePubName(indexVo.getName());
        order.setCompanyId(indexVo.getCompanyId());
        order.setCompanyName(indexVo.getCompanyName());
        order.setUserId(AuthInfoHolder.getUserId());
        order.setUserName(AuthInfoHolder.getAuthInfo().getUserName());
        order.setPrice(1L);
        order.setCreateDate(DateUtil.date());
        order.setStatus(OrdersConstants.ORDER_INIT_STATUS);
        this.save(order);
        return ResponseResult.okResult(order.getOrderNo());
    }

    /**
     * 查询是否支付成功
     *
     * @param orderNo
     * @return
     */
    @Override
    @GlobalTransactional
    public ResponseResult findPayResult(String orderNo) {
        //查询支付状态
        Boolean checkPayment = payTemplate.checkPayment(orderNo);
        //未支付则返回状态
        if (!checkPayment) {
            throw new BusinessException(ErrorCode.NOTPLAY);
        }
        //已支付 查询订单 状态
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getOrderNo, orderNo);
        Orders orders = this.getOne(queryWrapper);
        //如果是初始状态
        if (orders.getStatus().equals(OrdersConstants.ORDER_INIT_STATUS)) {
            //修改订单状态
            orders.setStatus(OrdersConstants.ORDER_PAID_STATUS);
            this.updateById(orders);
            //修改支付明细状态
            LambdaQueryWrapper<Payment> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(Payment::getOrderNo, orderNo);
            Payment payment = paymentService.getOne(queryWrapper1);
            payment.setStatus(OrdersConstants.PAID.toString());
            payment.setPayDate(DateUtil.date());
            paymentService.updateById(payment);
            //保存或修改选课记录
            RecordDto recordDto = new RecordDto();
            recordDto.setUserId(orders.getUserId());
            recordDto.setCoursePubId(orders.getCoursePubId());
            learningClient.saveRecord(recordDto);
        }
        //返回vo
        OrdersVo ordersVo = BeanHelper.copyProperties(orders, OrdersVo.class);
        return ResponseResult.okResult(ordersVo);
    }

    /**
     * 定时清理订单
     */
    @Override
    @GlobalTransactional
    public void clearOrders() {
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getStatus, OrdersConstants.ORDER_INIT_STATUS);
        Date oldDate = DateUtil.offsetMinute(new Date(), -15).toJdkDate();
        queryWrapper.lt(Orders::getCreateDate, oldDate);
        List<Orders> ordersList = this.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(ordersList)) {
            for (Orders orders : ordersList) {
                Boolean isPay = payTemplate.checkPayment(orders.getOrderNo());
                if (isPay) {
                    //修改订单状态
                    orders.setStatus(OrdersConstants.ORDER_PAID_STATUS);
                    this.updateById(orders);
                    //修改支付明细状态
                    LambdaQueryWrapper<Payment> queryWrapper1 = new LambdaQueryWrapper<>();
                    queryWrapper1.eq(Payment::getOrderNo, orders.getOrderNo());
                    Payment payment = paymentService.getOne(queryWrapper1);
                    payment.setStatus(OrdersConstants.PAID.toString());
                    payment.setPayDate(DateUtil.date());
                    paymentService.updateById(payment);
                    //保存或修改选课记录
                    RecordDto recordDto = new RecordDto();
                    recordDto.setUserId(orders.getUserId());
                    recordDto.setCoursePubId(orders.getCoursePubId());
                    learningClient.saveRecord(recordDto);
                } else {
                    //关闭订单
                    payTemplate.closeOrder(orders.getOrderNo());
                    orders.setStatus(OrdersConstants.ORDER_CLOSED_STATUS);
                    this.updateById(orders);
                }
            }
        } else {
            log.info("没有超时订单");
        }
    }
}
